package Judge;

import java.io.File;

import java.io.FileFilter;
import java.io.FileWriter;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import Config.Config;
import Util.ExternalProgramUtil;

public class JudgeFunction {

	/**
	 * 编译Java程序。
	 * @param program 源代码
	 * @param serial 在缓存中的文件名（不包括扩展名）
	 * @return 返回编译信息，如果出现问题，返回详细信息，否则返回succes
	 * @throws Exception 当文件异常、编译异常、网络异常、内部异常等异常发生时抛出
	 */
	public static String CompileJava(String program,String serial) throws Exception {
		String result="succes";
		String ProgramPath=Config.path+Config.systemPI+serial+".java";
		File f1=new File(ProgramPath);
		FileWriter fw=new FileWriter(f1);
		fw.write(program);
		fw.close();
		ExternalProgramUtil epu=new ExternalProgramUtil("javac -J-Duser.language=en "+ProgramPath);
		Thread.sleep(Config.CompileWaitTime);
		if(epu.getErrorinfo().equals("")==false) result=epu.getErrorinfo();
		return result;
	}
	
	/**
	 * 通过单个测试数据对Java程序进行评测。
	 * @param serial 在缓存中的文件名（不包括扩展名）
	 * @param inputData 输入数据
	 * @param outpuData 输出数据
	 * @param JudgeWaitTime 评测等待时间（时间限制）
	 * @return AC-完全正常 WA-结果错误 NO-没有结果 NF-没有文件 EO-错误输出非空
	 * @throws Exception 当文件异常、编译异常、网络异常、内部异常等异常发生时抛出
	 */
	public static String JudgeJava(String serial,String inputData,String outputData,int JudgeWaitTime) throws Exception{
		String result="AC";
		String ProgramPath=Config.path+Config.systemPI+serial+".class";
		File f1=new File(ProgramPath);
		if(f1.exists()==false) result="NF";
		ExternalProgramUtil epu=new ExternalProgramUtil("java -cp "+Config.path+" "+serial);
		epu.println(inputData);
		Thread.sleep(JudgeWaitTime);
		String answer=epu.getOutputinfo().replaceAll(" ", "");
		String errout=epu.getErrorinfo().replaceAll(" ", "");
		if(answer.equals(outputData)==false && answer.equals("")==false) result="WA";
		if(answer.equals("")==true) result="NO";
		if(errout.equals("")==false) result="EO-"+errout;
		epu.close();
		return result;
	}
	
	/**
	 * 执行正常评测，对程序进行编译并进行数据评测
	 * @param serial 在缓存中的文件名（不包括扩展名）,也是公开类名
	 * @param program 选手程序（直接给出）
	 * @param InputOutput json格式的测试数据 
	 * @param JudgeWaitTime 评测等待时间（时间限制）
	 * @return AC-完全正常 WA-结果错误 CE-编译错误 RE-运行时错误
	 * @throws Exception 当文件异常、编译异常、网络异常、内部异常等异常发生时抛出
	 */
	public static String JudgeJavaMData(String serial,String program,String InputOutput,int JudgeWaitTime) throws Exception {
		String result="AC";
		String filepath=Config.path+Config.systemPI+serial;
		String CompileResult=CompileJava(program, serial);
		if(CompileResult.equals("succes")==false){
			result="CE-"+CompileResult;
			File f1=new File(filepath+".java");
			if(f1.exists()==true) f1.delete();
			return result;
		}
		JSONObject jo=JSONObject.fromObject(InputOutput);
		JSONArray ja=jo.getJSONArray("data");
		int len=ja.size();
		String[] JudgeResults=new String[len];
		for(int i=0;i<len;++i){
			JSONObject jo2=ja.getJSONObject(i);
			String input=jo2.getString("input");
			String output=jo2.getString("output");
			JudgeResults[i]=JudgeJava(serial, input, output, JudgeWaitTime);
			if(JudgeResults[i].equals("WA")==true) result="WA";
			if(JudgeResults[i].equals("AC")==false && JudgeResults[i].equals("WA")==false) result="RE-"+JudgeResults[i];
		}
		File f1=new File(filepath+".java");
		File f2=new File(filepath+".class");
		if(f1.exists()==true) f1.delete();
		if(f2.exists()==true) f2.delete();
		return result;
	}
	
	//测试专用
	public static void main(String[] args) throws Exception {
		Config.systemPI="\\";
		Config.path="D:\\MyPrograms\\temp\\ZJOJ";
		String program="import java.io.*;import java.util.*;public class Main{public static void main(String args[]) throws Exception{Scanner cin=new Scanner(System.in);int a=cin.nextInt(),b=cin.nextInt();System.out.println(a+b)}}";
		String dataJSON="{\"data\":[{\"input\":\"1 1\",\"output\":\"2\"},{\"input\":\"2 2\",\"output\":\"4\"}]}";
		String result=JudgeJavaMData("Main", program, dataJSON, 1000);
		System.out.println(result);
	}
}
